package com.xteam.ecsystem.utils;

import java.util.Date;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

/**
 * javamail 邮件发送工具类
 * 包含了一个服务器验证类（内部类）
 * 
 * 1、支持发送普通邮件
 * 2、支持发送HTML格式邮件，并显示图片
 * 3、支持发送单个或多个附件的邮件
 * 
 * @author liuzhi
 *
 */
public class JavaMailUtil {

	/**
	 * SMTP 服务器
	 */
	private String hostname;
	
	/**
	 * 邮件用户名
	 */
	private String username;
	
	/**
	 * 密码
	 */ 
	private String password;
	
	/**
	 * 是否需要验证用户名和密码
	 */
	private boolean isValidate;
	
	/**
	 * 邮件头名称
	 */ 
	private String mail_head_name;
	
	/**
	 * 邮件头值
	 */ 
	private String mail_head_value;
	
	/** 
	 * 发件人邮件地址（发件人邮箱）
	 */ 
	private String mail_from;
	
	/** 
	 * 邮件接收地址（收件人邮箱）
	 */ 
	private String mail_to;
	
	/** 
	 * 邮件主题（邮件标题）
	 */ 
	private String mail_subject;
	
	/**
	 * 邮件内容类型、格式
	 */
	private String mail_content_type;
	
	/** 
	 * 邮件内容
	 */
	private String mail_content;
	
	/** 
	 * 邮件发送人名称
	 */
	private String personName;
	
	/**
	 * 附件地址列表
	 */
	private String[] attachmentPaths;
	
	
	public String getHostname() {
		return this.hostname;
	}

	public void setHostname(String hostname) {
		this.hostname = hostname;
	}

	public String getUsername() {
		return this.username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return this.password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public boolean isValidate() {
		return this.isValidate;
	}

	public void setValidate(boolean isValidate) {
		this.isValidate = isValidate;
	}
	
	public String getMail_head_name() {
		return this.mail_head_name;
	}

	public void setMail_head_name(String mail_head_name) {
		this.mail_head_name = mail_head_name;
	}

	public String getMail_head_value() {
		return this.mail_head_value;
	}

	public void setMail_head_value(String mail_head_value) {
		this.mail_head_value = mail_head_value;
	}

	public String getMail_to() {
		return this.mail_to;
	}

	public void setMail_to(String mail_to) {
		this.mail_to = mail_to;
	}

	public String getMail_from() {
		return this.mail_from;
	}

	public void setMail_from(String mail_from) {
		this.mail_from = mail_from;
	}

	public String getMail_subject() {
		return this.mail_subject;
	}

	public void setMail_subject(String mail_subject) {
		this.mail_subject = mail_subject;
	}

	public String getMail_content_type() {
		return this.mail_content_type;
	}

	public void setMail_content_type(String mail_content_type) {
		this.mail_content_type = mail_content_type;
	}
	
	public String getMail_content() {
		return this.mail_content;
	}

	public void setMail_content(String mail_content) {
		this.mail_content = mail_content;
	}

	public String getPersonName() {
		return this.personName;
	}

	public void setPersonName(String personName) {
		this.personName = personName;
	}
	
	public String[] getAttachmentPaths() {
		return this.attachmentPaths;
	}

	public void setAttachmentPaths(String[] attachmentPaths) {
		this.attachmentPaths = attachmentPaths;
	}
	
	/**
	 * JavaMailUtil无参构造方法
	 */
	public JavaMailUtil() {
		// 自动验证
		this.isValidate = true;
		// 自动设置邮件头名称
		this.mail_head_name = "mail_head_name";
		// 自动设置邮件头对应的值
		this.mail_head_value = "mail_head_value";
	}
	
	/**
	 * 服务器验证类（内部类）
	 * 针对用户名和密码进行验证
	 * 该类由用户指定是否需要用户名和密码的验证
	 * 验证条件：setValidate(true);
	 * @author liuzhi
	 *
	 */
	public class Email_Autherticator extends Authenticator{
		public Email_Autherticator()
	    {
	        super();
	    }

		/**
		 * 设置验证的用户名和密码 
		 * @param user
		 * @param pwd
		 */
	    public Email_Autherticator(String user, String pwd)
	    {
	        super();
	        setUsername(user);
	        setPassword(pwd);
	    }

	    /**
	     * 返回用来认证的用户名和密码
	     * @see javax.mail.Authenticator#getPasswordAuthentication()
	     */
	    public PasswordAuthentication getPasswordAuthentication()
	    {
	    	return new PasswordAuthentication(getUsername(), getPassword());
	    }
	}

	/**
	 * 发送普通邮件
	 * 
	 * @author liuzhi Jan 6, 2013
	 * @return
	 */
	public boolean sendNormalMail(){
		try {
			// 获取系统环境
			Properties prop = new Properties();
			Authenticator auth = null;
			
			// 判断发送邮件是否需要验证
			if(isValidate()){
				// 邮件服务器认证 用户名和密码 
				auth = new Email_Autherticator();
			}
			
			// 指定SMTP服务器
			prop.put("mail.smtp.host", hostname);
			// 指定是否需要SMTP验证 
			prop.put("mail.smtp.auth", "true");
			
			/**
			 * 设置会话和邮件服务器进行通讯
			 * 异常：java.lang.SecurityException: Access to default session denied
			 * 原因：Session.getDefaultInstance()是获得一个默认的共享session
			 * 
			 * 如果在创建Authenticator时直接创建，即直接（new Email_Autherticator()），便可以使用此方法。
			 */
//			Session session = Session.getDefaultInstance(prop, auth);
			// 设置会话和邮件服务器进行通讯  
			Session session = Session.getInstance(prop, auth);
			// 在控制台显示Debug信息  
			session.setDebug(false);  
			
			// 设置邮件对象  
			MimeMessage message = new MimeMessage(session);
			
			// 设置主题
			message.setSubject(getMail_subject());
			// 设置标题
			message.setHeader(getMail_head_name(), getMail_head_value());
			// 设置发送日期
			message.setSentDate(new Date());
			
			// 设置发信人地址和名字
			Address address = new InternetAddress(getMail_from(), getPersonName());
			// 把发件人信息添加到邮件对象中
			message.setFrom(address);
			
			// 设置收件人地址
			Address toAddress = new InternetAddress(getMail_to());
			// 把收件人信息添加到邮件对象中
			message.addRecipient(Message.RecipientType.TO, toAddress);
			
			// 设置邮件格式（普通邮件）  
			message.setContent("foobar", getMail_content_type());
			
			// 设置邮件内容（必须在设置文件格式后面） 
			message.setText(getMail_content());
			
			// 保存上面添加的信息（可省略） 
			message.saveChanges();
			
			// 发送邮件 
			Transport.send(message);
			System.out.println("普通邮件发送成功！");
			return true;
		} catch (Exception e) {
			System.out.println("普通邮件发送出错！");
			e.printStackTrace();
			return false;
		}
	}

  	/**
  	 * 发送HTML格式的邮件 
     * 支持HTML中带有图片并显示
     * 特点：
     * 1、图片存在于服务器上，因此不支持离线浏览；
     * 2、浏览邮件需要访问web服务；
     * 
  	 * @author liuzhi Jan 6, 2013
  	 * @return
  	 */
    public boolean sendHtmlMail(){     
    	try {
    		// 获取系统环境
			Properties prop = new Properties();
			Authenticator auth = null;
			
			// 判断发送邮件是否需要验证
			if(isValidate()){
				// 邮件服务器认证 用户名和密码 
				auth = new Email_Autherticator();
			}
			
			// 指定SMTP服务器
			prop.put("mail.smtp.host", hostname);
			// 指定是否需要SMTP验证 
			prop.put("mail.smtp.auth", "true");
			
			// 设置会话和邮件服务器进行通讯  
			Session session = Session.getInstance(prop, auth);
			// 在控制台显示Debug信息  
			session.setDebug(false);  
			
			// 设置邮件对象  
			MimeMessage message = new MimeMessage(session);     
              
			// 设置主题
			message.setSubject(getMail_subject());
			// 设置标题
			message.setHeader(getMail_head_name(), getMail_head_value());
			// 设置发送日期
			message.setSentDate(new Date());
			
			// 设置发信人地址和名字
			Address address = new InternetAddress(getMail_from(), getPersonName());
			// 把发件人信息添加到邮件对象中
			message.setFrom(address);
			
			// 设置收件人地址
			Address toAddress = new InternetAddress(getMail_to());
			// 把收件人信息添加到邮件对象中
			message.addRecipient(Message.RecipientType.TO, toAddress);     
                
            //设置邮件格式（HTML邮件） 
//			mail_content_type = "text/html; charset=utf-8";  
            message.setContent(getMail_content(), getMail_content_type());   
  
            // 保存上面添加的信息（可省略） 
 			message.saveChanges();
 			
 			// 发送邮件 
 			Transport.send(message);
 			System.out.println("HTML邮件发送成功！");  
 			return true;
		} catch (Exception e) {
			System.out.println("HTML邮件发送失败！");
			e.printStackTrace();
			return false;
		}  
            
    }     

	/**
	 * 发送带有附件的邮件
	 * 特点：
	 * 1、支持同时发送单个或多个附件
	 * 2、不能针对HTML格式内容进行排版
	 * 
	 * @author liuzhi Jan 6, 2013
	 * @return
	 */
    public boolean sendAttachmentMail(){     
    	try {
    		// 获取系统环境
			Properties prop = new Properties();
			Authenticator auth = null;
			
			// 判断发送邮件是否需要验证
			if(isValidate()){
				// 邮件服务器认证 用户名和密码 
				auth = new Email_Autherticator();
			}
			
			// 指定SMTP服务器
			prop.put("mail.smtp.host", hostname);
			// 指定是否需要SMTP验证 
			prop.put("mail.smtp.auth", "true");
			
			// 设置会话和邮件服务器进行通讯  
			Session session = Session.getInstance(prop, auth);
			// 在控制台显示Debug信息  
			session.setDebug(false);  
			
			// 设置邮件对象  
			MimeMessage message = new MimeMessage(session);     
              
			// 设置主题
			message.setSubject(getMail_subject());
			// 设置标题
			message.setHeader(getMail_head_name(), getMail_head_value());
			// 设置发送日期
			message.setSentDate(new Date());
			
			// 设置发信人地址和名字
			Address address = new InternetAddress(getMail_from(), getPersonName());
			// 把发件人信息添加到邮件对象中
			message.setFrom(address);
			
			// 设置收件人地址
			Address toAddress = new InternetAddress(getMail_to());
			// 把收件人信息添加到邮件对象中
			message.addRecipient(Message.RecipientType.TO, toAddress);     
                
            // 设置邮件格式（带附件的邮件）
//            message.setContent(getMail_content(), getMail_content_type());   
              
            BodyPart messageBodyPart = new MimeBodyPart();     
            messageBodyPart.setText(getMail_content());     
              
//            MimeMultipart mmp = new MimeMultipart();
//            mmp.setSubType("related");
            Multipart multipart = new MimeMultipart();   
            multipart.addBodyPart(messageBodyPart);     
              
            DataSource source = null;
            if (getAttachmentPaths() != null && getAttachmentPaths().length > 0) {
				for (int i = 0; i < getAttachmentPaths().length; i++) {
					 messageBodyPart = new MimeBodyPart(); 
					 
					 source = new FileDataSource(getAttachmentPaths()[i]);   
					 messageBodyPart.setDataHandler(new DataHandler(source));
					 /**
					  *  设置发送之后的文件名名称
					  *  MimeUtility.encodeWord(String str) 针对中文文件名称解码
					  */
			         messageBodyPart.setFileName(MimeUtility.encodeWord(getAttachmentPaths()[i]));
			         
			         multipart.addBodyPart(messageBodyPart); 
				}
			}
              
            message.setContent(multipart);     
              
            // 保存上面添加的信息  
            message.saveChanges();     
            //  发送邮件   
            Transport.send(message);     
            System.out.println("附件邮件发送成功！"); 
            return true;
		} catch (Exception e) {
			System.out.println("附件邮件发送失败！"); 
			e.printStackTrace();
			return false;
		}    
         
    }     

    
	/**
	 * mian方法测试
	 * 
	 * @author liuzhi Jan 6, 2013
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			/*JavaMailUtil mailTool = new JavaMailUtil();
			mailTool.setHostname("smtp.163.com");
			mailTool.setUsername("liuzhi_struggle@163.com");
			mailTool.setPassword("mail.163.liuzhi");
			mailTool.setValidate(true);
			mailTool.setMail_head_name("mail_head_name");
			mailTool.setMail_head_value("mail_head_value");
			mailTool.setMail_to("271831866@qq.com");
			mailTool.setMail_from("liuzhi_struggle@163.com");
			mailTool.setMail_subject("九颗米测试邮件");
			mailTool.setPersonName("九颗米");*/
			
			/*在CustomerServlet.java中测试sendNormalMail()方法通过，在此main方法中测试报错！*/
			/*mailTool.setMail_content_type("application/x-foobar");
			String sendContent = "测试发送普通邮件！！！";
			mailTool.setMail_content(sendContent);
			mailTool.sendNormalMail();*/
			
			/*在CustomerServlet.java中测试sendHtmlMail()方法通过，在此main方法中测试报错！*/
			/*mailTool.setMail_content_type("text/html;charset=utf-8");
			String sendContent = 
					"<html>" 
					+  "<head></head>" 
					+  "<body>" 
					+	  "<font style='color:red;font-weight:bold;'>测试发送HTML邮件！！！</font><br/>" 
					+	  "<a href='http://www.baidu.com' style='text-decoration:none;'>点击到百度首页</a>"
					+     "<table border='0' cellpadding='0' cellspacing='0' width='600px' align='center'><caption style='color:blue;font-weight:bold;'>测试表格</caption><tr><td align='center'>内容1</td><td align='center'>内容2</td></tr><tr><td colspan='2'><img src='http://localhost:8080/test/images/bg1.jpg' alt='暂无图片' /></td></tr></table>"
					+  "</body>" 
					+"</html>";
			mailTool.setMail_content(sendContent);
			mailTool.sendHtmlMail();*/
			
			/*在CustomerServlet.java中测试sendAttachmentMail()方法通过，在此main方法中测试报错！*/
			/*String sendContent = "测试发送带附件的邮件，不支持HTML格式！！！";
			mailTool.setMail_content(sendContent);
			String[] attachmentPaths = {"E:\\证书.png","E:\\电话薄.txt"};
			mailTool.setAttachmentPaths(attachmentPaths);
			mailTool.sendAttachmentMail();*/
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}
